package ua.cs.stu.ics.dbf.readers;

import com.linuxense.javadbf.DBFException;
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFReader;
import ua.cs.stu.ics.dbf.DBReaderFactory;
import ua.cs.stu.ics.dbf.exceptions.DBException;
import ua.cs.stu.ics.dbf.utils.Util;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.MissingResourceException;

/**
 * Created by IntelliJ IDEA.
 * User: Admin
 * Date: 13.02.11
 * Time: 13:15
 * To change this template use File | Settings | File Templates.
 */
public abstract class DBFAbstractReader<DOMEN> {

    protected abstract void add(DOMEN d);
    protected abstract DOMEN createDomain();

    private DOMEN domen;

    public void read(String fileName) throws DBException, DBFException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
        DBFField[] fields = null;
        DBReaderFactory dbr = new DBReaderFactory();
        DBFReader reader = null;

        try {
            InputStream is = Util.checkInputStream(fileName);
            if (is != null) {
                reader = new DBFReader(is);
                reader.setCharactersetName("866");
                int fieldCount = reader.getFieldCount();
                fields = new DBFField[fieldCount];
                for (int i = 0; i < fieldCount; i++)
                    fields[i] = reader.getField(i);
            }
        } catch (DBFException e) {
            throw new DBException(e.getMessage());
        }

        Object[] rowObjects;


        while ((rowObjects = reader.nextRecord()) != null) {
            domen = createDomain();
            for (int i = 0; i < rowObjects.length; i++) {
                if (rowObjects[i] == null)
                    continue;
                invokeSet(fields[i].getName(), rowObjects[i], rowObjects[i].getClass());
            }
            add(domen);
        }
    }

    private void invokeSet(String field, Object o, Class clazz) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, DBException {
        Method m = domen.getClass().getMethod(Util.convertToJavaName(field, "set"), clazz);
        if (m == null)
            throw new DBException("Cant find writeble field " + field);
        m.invoke(domen, new Object[]{o});//invoke setter
    }

}
